#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <string.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <sys/types.h>


#define SERVER_PORT 8080 // 定义FTP服务器监听的端口号
#define BUFSIZE 1024	 // 定义缓冲区大小

void *send_text_thread(void *args);
void *recv_text_thread(void *args);
int recv_file(int socket_desc,const char filename[]);

// 定义足够大的缓冲区来存储IP地址字符串
char client_ip[INET_ADDRSTRLEN]; 

int main()
{
	int server_socket, client_socket;			 // 服务器和客户端的socket描述符
	struct sockaddr_in server_addr, client_addr; // 服务器和客户端的地址信息
	socklen_t client_len = sizeof(client_addr);	 // 客户端地址信息的长度

	// 创建服务器端的socket
	server_socket = socket(AF_INET, SOCK_STREAM, 0);
	if (server_socket < 0)
	{
		perror("Socket creation failed");
		exit(EXIT_FAILURE);
	}

	// 设置服务器地址结构
	memset(&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = INADDR_ANY;
	server_addr.sin_port = htons(SERVER_PORT);

	// 绑定socket到指定的地址和端口
	if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
	{
		perror("Bind failed");
		exit(EXIT_FAILURE);
	}

	// 开始监听端口，等待客户端连接
	listen(server_socket, 5);
	printf("FTP Server is listening on port %d...\n", SERVER_PORT);


	// 定义线程的标识符
	pthread_t recv_thread,send_thread;
	
	// 主循环：接受客户端连接并处理
	while (1)
	{
		client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_len);
		if (client_socket < 0)
		{
			perror("Accept failed");
			continue;
		}
		// 获取客户端地址信息后，将其转换为点分十进制的IP地址字符串
		inet_ntop(AF_INET, &client_addr.sin_addr, client_ip, sizeof(client_ip));
		printf("Accepted connection from client IP: %s\n", client_ip);

		/**
		 * 这里处理连接
		**/

		// 接收文件
		recv_file(client_socket,"接收的文件.txt");

		if(pthread_create(&recv_thread,NULL,recv_text_thread,(void *)&client_socket))
		{
			perror("Error creating recv thread");
		}
		
		if(pthread_create(&send_thread,NULL,send_text_thread,(void *)&client_socket))
		{
			perror("Error creating send thread");
		}
		
	}

	pthread_join(recv_thread, NULL);
	pthread_join(send_thread, NULL);
	close(client_socket); // 关闭客户端连接
	close(server_socket); // 关闭服务器socket
	return 0;
}

void *send_text_thread(void *args)
{
	int *client_socket = (int *)args;
	while (1)
	{
		char buff[BUFSIZE];
		printf("请输入消息：");
		scanf("%s", buff);
		int buff_len = strlen(buff);
		ssize_t sent_bytes = send(*client_socket, buff, buff_len, 0); // 发送数据
		// 检查发送结果
		if (sent_bytes == -1)
		{
			// 发送失败
			perror("发送失败");
		}
		else if (sent_bytes < buff_len)
		{
			// 发送的字节数少于预期
			printf("警告：未能发送所有数据。已发送 %zd 字节，共 %d 字节。\n", sent_bytes, buff_len);
		}
		else
		{
			// 发送成功
			printf("消息已成功发送。\n");
		}
	}
}
void *recv_text_thread(void *args)
{
	int *client_socket = (int *)args;
	while (1) // 当 client_socket_flag被设置为0时持续接收
	{
		char buff[BUFSIZE];
		ssize_t recv_bytes = recv(*client_socket, buff, BUFSIZE, 0); // 接收数据
		// 检查接收结果
		if (recv_bytes == -1)
		{
			// 接收失败
			perror("接收失败");
		}
		else if (recv_bytes == 0)
		{
			// 连接关闭
			// printf("连接已关闭。\n");
			break;
		}
		else
		{
			// 打印接收到的文本
			printf("收到消息：%s\n", buff);
		}

		if (strcmp(buff, "exit") == 0)
		{
			break;
		}
	}
	printf("Client with IP address: %s has disconnected.\n", client_ip);
}

int recv_file(int socket_desc, const char filename[])
{
    int file_size;
    char *data;
    
    // 接收客户端发送的文件大小
    if (recv(socket_desc, &file_size, sizeof(int), 0) != sizeof(int)) {
        perror("Failed to receive file size");
        return -1;
    }

    // 根据文件大小动态分配内存并检查分配是否成功
    data = malloc(file_size + 1);
    if (data == NULL) {
        perror("Failed to allocate memory for file data");
        return -1;
    }

    // 创建一个新文件
    FILE *fp = fopen(filename, "w");
    if (fp == NULL) {
        perror("Failed to open file for writing");
        free(data);
        return -1;
    }

    // 接收文件数据
    int total_received = 0;
    while (total_received < file_size) {
        int bytes_received = recv(socket_desc, data + total_received, file_size - total_received, 0);

        if (bytes_received <= 0) {
            perror("Error receiving file data");
            free(data);
            fclose(fp);
            return -1;
        }

        total_received += bytes_received;
    }

    // 写入文件
    fwrite(data, 1, file_size, fp);

    // 清理资源
    free(data);
    fclose(fp);

    return 1;
}
